package org.feng.datasource.aop;

import jakarta.annotation.PostConstruct;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.feng.datasource.DynamicDataSourceContextHolder;
import org.feng.datasource.annotation.ChangeDataSource;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 动态数据源切面
 *
 * @author feng
 */
@Aspect
@Component
@Order(1)
@Slf4j
public class DynamicDataSourceAspect {

    @SneakyThrows
    @Before("@annotation(org.feng.datasource.annotation.ChangeDataSource)")
    public void changeDataSource(JoinPoint joinPoint) {
        log.info("开始切换数据源...");

        // 获取方法名，参数
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        Class<?>[] paramsTypes = new Class[args.length];
        if(args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                paramsTypes[i] = args[i].getClass();
            }
        }

        // 获取注解
        Class<?> aClass = joinPoint.getTarget().getClass();
        Method currentMethod = aClass.getDeclaredMethod(methodName, paramsTypes);
        ChangeDataSource changeDataSource = currentMethod.getDeclaredAnnotation(ChangeDataSource.class);
        // 获取租户
        String merchant = changeDataSource.merchant();
        log.info("当前数据源租户切换为：{}", merchant);

        // 切换数据源
        DynamicDataSourceContextHolder.setDataSourceKey(merchant);
    }


    @After("@annotation(org.feng.datasource.annotation.ChangeDataSource)")
    public void changeDataSourceOver() {
        log.info("释放数据源...");
        DynamicDataSourceContextHolder.removeDataSourceKey();
    }

    @PostConstruct
    private void init() {
        log.info("注册动态数据源切换注解");
    }
}
